home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Expert
/
Windows Expert.iso
/
windownt
/
wvnsrc75.zip
/
WVSCREEN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-06
|
17KB
|
616 lines
/*-- First Line of WVSCREEN.C -- Contains Screen-related functions. */
#include "windows.h"
#include "wvglob.h"
#include "winvn.h"
/*--- function ScreenDown ----------------------------------------------
*
* Advance a pointer "nLines" lines through the textlines.
* However, do not go so far that less than LinesOnScreen lines
* are left past the pointer.
*
* This is used to implement "PageDown" and "LineDown" functions.
*
* Entry nLines Number of lines to move the pointer.
* LinesOnScreen is the number of lines on the screen.
* BlockPtr Pointer to block containing line.
* LinePtr Pointer to the given line.
*
* Exit BlockPtr and LinePtr (may) have been moved to a new line.
* LinesAdvanced is the number of lines actually moved--can be
* less than nLines if we hit the top of the
* last screen.
*/
void
ScreenDown (nLines, LinesOnScreen, BlockPtr, LinePtr, LinesAdvanced)
int nLines;
int LinesOnScreen;
TypBlock far **BlockPtr;
TypLine far **LinePtr;
int *LinesAdvanced;
{
TypBlock far *MyBlock = *BlockPtr;
TypLine far *MyLine = *LinePtr;
int LinesGone;
int TestAdvance;
HANDLE hBlock, hBlockGarbage;
unsigned int Offset, OffsetGarbage;
TypLineID LineIDGarbage, MyLineID;
/* Skip forward nLines, plus one screen's worth, just to see */
/* if there are enough lines ahead of us in the document. */
PtrToOffset (MyBlock, MyLine, &hBlock, &Offset, &MyLineID);
TestAdvance = nLines + LinesOnScreen - 1;
for (LinesGone = TestAdvance; LinesGone && NextLine (&MyBlock, &MyLine);
LinesGone--);
UnlockLine (MyBlock, MyLine, &hBlockGarbage, &OffsetGarbage, &LineIDGarbage);
nLines -= LinesGone;
if (nLines < 0)
nLines = 0;
*LinesAdvanced = nLines;
LockLine (hBlock, Offset, MyLineID, &MyBlock, &MyLine);
while (nLines--)
{
NextLine (BlockPtr, LinePtr);
}
}
/*--- function ScreenUp ----------------------------------------------
*
* Back up a pointer "nLines" lines through the textlines.
* However, do not go past the beginning of the document.
*
* This is used to implement "PageUp" and "LineUp" functions.
*
* Entry nLines Number of lines to move the pointer.
* BlockPtr Pointer to block containing line.
* LinePtr Pointer to the given line.
*
* Exit BlockPtr and LinePtr (may) have been moved to a new line.
* LinesBackedUp is the number of lines actually moved--can be
* less than nLines if we hit beginning of doc.
*/
void
ScreenUp (nLines, BlockPtr, LinePtr, LinesBackedUp)
int nLines;
TypBlock far **BlockPtr;
TypLine far **LinePtr;
int *LinesBackedUp;
{
*LinesBackedUp = 0;
while (nLines-- && PrevLine (BlockPtr, LinePtr))
{
(*LinesBackedUp)++;
}
}
/*--- function ScrollIt ----------------------------------------------
*
* Perform a scrolling action.
*
* Entry Document points to a document
* wParam is the wParam argument given from a WM_VSCROLL
* window message. (One of the SB_ symbols.)
* lParam is the lParam argument.
*/
void
NewScrollIt (Document, wParam, lParam)
TypDoc *Document;
WORD wParam;
DWORD lParam;
{
TypBlock far *BlockPtr, far * NewBlockPtr;
TypLine far *LinePtr, far * NewLinePtr;
int LinesGone;
unsigned int LineOrd;
RECT Rect;
switch (wParam)
{
case SB_LINEUP:
/* Move up a line by scrolling the window down one line */
/* and introducing 1 new line at the top. */
if (Document->TopLineOrd > 0) {
LinesGone = 1;
}
else LinesGone = 0;
doscrollup:;
if (LinesGone)
{
Rect.left = 0;
Rect.right = Document->ScXWidth;
Document->TopLineOrd -= LinesGone;
ScrollWindow (Document->hDocWnd, 0, LinesGone * LineHeight, NULL, NULL);
Rect.top = TopSpace;
Rect.bottom = TopSpace + LinesGone * LineHeight;
InvalidateRect (Document->hDocWnd, &Rect, FALSE);
/* Make sure garbage at bottom is erased in WM_PAINT processing */
Rect.top = TopSpace + Document->ScYLines * LineHeight;
Rect.bottom = Document->ScYHeight;
InvalidateRect (Document->hDocWnd, &Rect, FALSE);
}
break;
case SB_LINEDOWN:
if (Document->TopLineOrd < (Document->TotalLines - Document->ScYLines)) {
LinesGone = 1;
}
else LinesGone = 0;
doscrolldown:;
if (LinesGone)
{
Document->TopLineOrd += LinesGone;
Rect.left = 0;
Rect.right = Document->ScXWidth;
ScrollWindow (Document->hDocWnd, 0, -LinesGone * LineHeight, NULL, NULL);
Rect.top = TopSpace + (Document->ScYLines - LinesGone) * LineHeight;
Rect.bottom = Document->ScYHeight;
InvalidateRect (Document->hDocWnd, &Rect, FALSE);
/* Make sure garbage at top is erased in WM_PAINT processing */
Rect.top = 0;
Rect.bottom = TopSpace;
InvalidateRect (Document->hDocWnd, &Rect, FALSE);
}
break;
case SB_PAGEUP:
/* LockLine (Document->hCurTopScBlock, Document->TopScOffset, Document->TopScLineID, &BlockPtr, &LinePtr); */
/* ScreenUp (Document->ScYLines - 1, &BlockPtr, &LinePtr, &LinesGone); */
LinesGone= Document->TopLineOrd - (Document->ScYLines - 1);
if (LinesGone > 0) {
LinesGone = Document->ScYLines - 1;
}
else {
LinesGone = Document->TopLineOrd;
}
Document->TopLineOrd -= LinesGone;
InvalidateRect (Document->hDocWnd, NULL, FALSE);
break;
case SB_PAGEDOWN:
if ((Document->TotalLines - (Document->TopLineOrd + Document->ScYLines)) > Document->ScYLines)
LinesGone = Document->ScYLines - 1;
else
LinesGone = Document->TotalLines
- (Document->TopLineOrd + Document->ScYLines );
Document->TopLineOrd += LinesGone;
InvalidateRect (Document->hDocWnd, NULL, FALSE);
break;
case SB_THUMBPOSITION:
LineOrd = LOWORD (lParam);
/* if (!FindLineOrd (Document, LineOrd, &BlockPtr, &LinePtr))
{
return;
}
*/
doposition:;
Document->TopLineOrd = LineOrd;
InvalidateRect (Document->hDocWnd, NULL, FALSE);
break;
case SB_THUMBTRACK:
LineOrd = LOWORD (lParam);
/* if (!FindLineOrd (Document, LineOrd, &BlockPtr, &LinePtr))
{
return;
}
*/
LinesGone = LineOrd - Document->TopLineOrd;
if (LinesGone > 0)
{
if (LinesGone >= (Document->ScYLines - 1))
{
goto doposition;
}
else
{
goto doscrolldown;
}
}
else if (LinesGone < 0)
{
LinesGone = -LinesGone;
if (LinesGone >= (Document->ScYLines - 1))
{
goto doposition;
}
else
{
goto doscrollup;
}
}
break;
default:
return;
break;
}
/* UnlockLine (BlockPtr, LinePtr, &(Document->hCurTopScBlock),
&(Document->TopScOffset), &(Document->TopScLineID));
*/
}
/*--- function ScrollIt ----------------------------------------------
*
* Perform a scrolling action.
*
* Entry Document points to a document
* wParam is the wParam argument given from a WM_VSCROLL
* window message. (One of the SB_ symbols.)
* lParam is the lParam argument.
*/
void
ScrollIt (Document, wParam, lParam)
TypDoc *Document;
WORD wParam;
DWORD lParam;
{
TypBlock far *BlockPtr, far * NewBlockPtr;
TypLine far *LinePtr, far * NewLinePtr;
int LinesGone;
unsigned int LineOrd;
RECT Rect;
int window_lineheight;
if (Document->DocType == DOCTYPE_ARTICLE)
window_lineheight = ArtLineHeight;
else
window_lineheight = LineHeight;
switch (wParam)
{
case SB_LINEUP:
/* Move up a line by scrolling the window down one line */
/* and introducing 1 new line at the top. */
LockLine (Document->hCurTopScBlock, Document->TopScOffset, Document->TopScLineID, &BlockPtr, &LinePtr);
ScreenUp (1, &BlockPtr, &LinePtr, &LinesGone);
doscrollup:;
if (LinesGone)
{
Rect.left = 0;
Rect.right = Document->ScXWidth;
Document->TopLineOrd -= LinesGone;
#if 0
Rect.top = TopSpace;
Rect.bottom = Document->ScYHeight;
ScrollWindow (Document->hDocWnd, 0, LinesGone * window_lineheight, &Rect, &Rect);
#endif
ScrollWindow (Document->hDocWnd, 0, LinesGone * window_lineheight, NULL, NULL);
#ifdef MAC
Rect.top = 0;
Rect.bottom = LinesGone * window_lineheight;
#else
Rect.top = TopSpace;
Rect.bottom = TopSpace + LinesGone * window_lineheight;
#endif
InvalidateRect (Document->hDocWnd, &Rect, FALSE);
/* Make sure garbage at bottom is erased in WM_PAINT processing */
Rect.top = TopSpace + Document->ScYLines * window_lineheight;
Rect.bottom = Document->ScYHeight;
InvalidateRect (Document->hDocWnd, &Rect, FALSE);
}
break;
case SB_LINEDOWN:
LockLine (Document->hCurTopScBlock, Document->TopScOffset, Document->TopScLineID, &BlockPtr, &LinePtr);
ScreenDown (1, Document->ScYLines, &BlockPtr, &LinePtr, &LinesGone);
doscrolldown:;
if (LinesGone)
{
Document->TopLineOrd += LinesGone;
Rect.left = 0;
Rect.right = Document->ScXWidth;
#if 0
Rect.top = TopSpace;
Rect.bottom = Document->ScYHeight;
ScrollWindow (Document->hDocWnd, 0, -LinesGone * window_lineheight, &Rect, &Rect);
#endif
ScrollWindow (Document->hDocWnd, 0, -LinesGone * window_lineheight, NULL, NULL);
#ifdef MAC
Rect.top = (Document->ScYLines - LinesGone) * window_lineheight;
Rect.bottom = Document->ScYHeight;
#else
Rect.top = TopSpace + (Document->ScYLines - LinesGone) * window_lineheight;
Rect.bottom = Document->ScYHeight;
#endif
InvalidateRect (Document->hDocWnd, &Rect, FALSE);
/* Make sure garbage at top is erased in WM_PAINT processing */
Rect.top = 0;
Rect.bottom = TopSpace;
InvalidateRect (Document->hDocWnd, &Rect, FALSE);
}
break;
case SB_PAGEUP:
LockLine (Document->hCurTopScBlock, Document->TopScOffset, Document->TopScLineID, &BlockPtr, &LinePtr);
ScreenUp (Document->ScYLines - 1, &BlockPtr, &LinePtr, &LinesGone);
Document->TopLineOrd -= LinesGone;
InvalidateRect (Document->hDocWnd, NULL, FALSE);
break;
case SB_PAGEDOWN:
LockLine (Document->hCurTopScBlock, Document->TopScOffset, Document->TopScLineID, &BlockPtr, &LinePtr);
ScreenDown (Document->ScYLines - 1, Document->ScYLines,
&BlockPtr, &LinePtr, &LinesGone);
Document->TopLineOrd += LinesGone;
InvalidateRect (Document->hDocWnd, NULL, FALSE);
break;
case SB_THUMBPOSITION:
LineOrd = LOWORD (lParam);
if (!FindLineOrd (Document, LineOrd, &BlockPtr, &LinePtr))
{
return;
}
doposition:;
Document->TopLineOrd = LineOrd;
InvalidateRect (Document->hDocWnd, NULL, FALSE);
break;
case SB_THUMBTRACK:
LineOrd = LOWORD (lParam);
if (!FindLineOrd (Document, LineOrd, &BlockPtr, &LinePtr))
{
return;
}
LinesGone = LineOrd - Document->TopLineOrd;
if (LinesGone > 0)
{
if (LinesGone >= (Document->ScYLines - 1))
{
goto doposition;
}
else
{
goto doscrolldown;
}
}
else if (LinesGone < 0)
{
LinesGone = -LinesGone;
if (LinesGone >= (Document->ScYLines - 1))
{
goto doposition;
}
else
{
goto doscrollup;
}
}
break;
default:
return;
break;
}
UnlockLine (BlockPtr, LinePtr, &(Document->hCurTopScBlock),
&(Document->TopScOffset), &(Document->TopScLineID));
#ifdef MAC
/* SendMessage(Document->hDocWnd,WM_PAINT,0,0L); */
MyUpdateWindow (Document->hDocWnd);
#endif
}
/*--- function LineOnScreen ----------------------------------------
*
* Determine whether a given line is displayed on the screen.
* If it is, give the ordinal line number on the screen.
*
* Entry Doc points to the document.
* hTargBlock is the handle of the block containing the line.
* TargOffset is the offset of the target line.
* TargLineID is the line's ID.
*
* Exit returns -1 if the line is not on the screen, else
* the ordinal line number (0 = top line, etc.)
*/
int
LineOnScreen (Doc, hTargBlock, TargOffset, TargLineID)
TypDoc *Doc;
HANDLE hTargBlock;
unsigned int TargOffset;
TypLineID TargLineID;
{
TypBlock far *CurBlockPtr, far * TargBlockPtr;
TypLine far *CurLinePtr, far * TargLinePtr;
int iline;
BOOL found = FALSE;
HANDLE hBlock;
unsigned int Offset;
TypLineID MyLineID;
LockLine (Doc->hCurTopScBlock, Doc->TopScOffset, Doc->TopScLineID, &CurBlockPtr, &CurLinePtr);
LockLine (hTargBlock, TargOffset, TargLineID, &TargBlockPtr, &TargLinePtr);
for (iline = 0; !found && iline < Doc->ScYLines; iline++)
{
found = (TargLinePtr == CurLinePtr);
if (!found)
{
NextLine (&CurBlockPtr, &CurLinePtr);
}
}
UnlockLine (CurBlockPtr, CurLinePtr, &hBlock, &Offset, &MyLineID);
UnlockLine (TargBlockPtr, TargLinePtr, &hBlock, &Offset, &MyLineID);
if (!found)
iline = 0;
return (iline - 1);
}
/*--- function NextWindow ----------------------------------------------
*
* Makes another window the active window with input focus.
* This function would typically be used to implement a keystroke
* (usually F6) that switches windows.
*
* Entry Doc points to the current document.
*/
void
NextWindow (Doc)
TypDoc *Doc;
{
int idoc;
int trydoctype;
TypDoc *NewDoc;
/* First, locate the current window in our data structures. */
switch (Doc->DocType)
{
case DOCTYPE_NET:
idoc = 0;
trydoctype = DOCTYPE_GROUP;
break;
case DOCTYPE_GROUP:
for (idoc = 0; idoc < MAXGROUPWNDS && Doc != &(GroupDocs[idoc]); idoc++);
if (idoc >= MAXGROUPWNDS)
{
MessageBox (Doc->hDocWnd, "Error finding next window", "System error", MB_ICONHAND | MB_OK);
}
trydoctype = DOCTYPE_GROUP;
idoc++;
break;
case DOCTYPE_ARTICLE:
for (idoc = 0; idoc < MAXARTICLEWNDS && Doc != &(ArticleDocs[idoc]); idoc++);
if (idoc >= MAXARTICLEWNDS)
{
MessageBox (Doc->hDocWnd, "Error finding next window", "System error", MB_ICONHAND | MB_OK);
}
trydoctype = DOCTYPE_ARTICLE;
idoc++;
break;
}
/* Now, find the next window in the sequence. */
if (trydoctype == DOCTYPE_GROUP)
{
for (; idoc < MAXGROUPWNDS; idoc++)
{
if (GroupDocs[idoc].InUse)
{
NewDoc = ActiveGroupDoc = &(GroupDocs[idoc]);
goto foundit;
}
}
idoc = 0;
}
/* Not found yet--try to find an Article doc. */
for (; idoc < MAXARTICLEWNDS; idoc++)
{
if (ArticleDocs[idoc].InUse)
{
NewDoc = ActiveArticleDoc = &(ArticleDocs[idoc]);
goto foundit;
}
}
/* Still not found--just make the Net document the next one. */
NewDoc = &NetDoc;
foundit:;
SetActiveWindow (NewDoc->hDocWnd);
SetFocus (NewDoc->hDocWnd);
}
/*--- function AdjustScTop -----------------------------------
*
* Adjust the top line of the screen so that a given line is sure
* to appear on the screen.
* Don't do anything if the document is one screen's length or smaller.
*
* Entry
* BlockPtr and LinePtr point to the line we want to
* make sure is visible.
*
* Exit Doc's TopSc fields have been set to ensure that
* the line will appear on the screen.
* The line has been unlocked.
*/
void
AdjustTopSc (BlockPtr, LinePtr)
TypBlock far *BlockPtr;
TypLine far *LinePtr;
{
unsigned int lineord;
TypDoc *Doc;
HANDLE hBlock;
unsigned int Offset;
TypLineID MyLineID;
Doc = BlockPtr->OwnerDoc;
if (Doc->TotalLines > Doc->ScYLines)
{
lineord = WhatLine (BlockPtr, LinePtr);
while (lineord > Doc->TotalLines - Doc->ScYLines)
{
PrevLine (&BlockPtr, &LinePtr);
lineord--;
}
Doc->TopLineOrd = lineord;
UnlockLine (BlockPtr, LinePtr, &(Doc->hCurTopScBlock),
&(Doc->TopScOffset), &(Doc->TopScLineID));
}
else
{
UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
}
}
/*--- function ScreenToTop -------------------------------------
*
* Sets a document so that the screen is scrolled to the top.
*
* Entry Doc points to the document.
*
* Exit The document has been set to display starting at
* the first line.
*/
void
ScreenToTop (TypDoc * Doc)
{
Doc->hCurTopScBlock = Doc->hFirstBlock;
Doc->TopScOffset = sizeof (TypBlock);
Doc->TopScLineID = 0;
Doc->TopLineOrd = 0;
}
/*-- Last Line of WVSCREEN.C ----------------- */